#ifndef CAdresseH
#define CAdresseH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include "CEdit.h"
#include "CComboBx.h"
#include "CAdressePanel.h"
#include "CtrlStd.h"
//---------------------------------------------------------------------------

#define ADR_REC_ALL         0xFF   //Recherche toutes les fiches
#define ADR_REC_NUMERO      0x01   //Recherche en fonction du numéro de fiche
#define ADR_REC_SOCIETE     0x02   //Recherche en fonction du nom de société
#define ADR_REC_CATEGORIE   0x04   //Recherche en fonction de la catégorie de la fiche
#define ADR_REC_NOM         0x08   //Recherche en fonction du nom
#define ADR_REC_PRENOM      0x10   //Recherche en fonction du prénom

#define NB_CAR_CATEG        81   //Nombre de caractères de la catégorie
#define NB_CAR_TITRE        41   //Nombre de caractères du titre
#define NB_CAR_NOM          61   //Nombre de caractères du nom
#define NB_CAR_PRENOM       61   //Nombre de caractères du prénom
#define NB_CAR_FONCTION     61   //Nombre de caractères de la fonction
#define NB_CAR_SOCIETE      61   //Nombre de caractères de la societe
#define NB_CAR_TEL          41   //Nombre de caractères du téléphone
#define NB_CAR_FAX          41   //Nombre de caractères du fax
#define NB_CAR_EMAIL        61   //Nombre de caractères de l'e-mail
#define NB_CAR_SITEWEB      61   //Nombre de caractères du site web

#define NB_CAR_RIB_DESIGNATION 26  // Nombre de caractères de la désignation (Avec \0)
#define NB_CAR_RIB_BANQUE       6  // Nombre de caractères de la banque (Avec \0)
#define NB_CAR_RIB_GUICHET      6  // Nombre de caractères du guichet (Avec \0)
#define NB_CAR_RIB_COMPTE      12  // Nombre de caractères du compte (Avec \0)
#define NB_CAR_RIB_CLE          3  // Nombre de caractères de la clé (Avec \0)

enum eTypeOuverture
   {
   eSansSelection,        //Aucune fiche ne peut être choisie
   eSelectionSimple,      //Une seule fiche peut-être choisie
   eSelectionMultiple    //Plusieurs fiches peuvent être choisies
   };

class sConfigCarnAdr
   {
   public :
      eTypeOuverture ChoixSelection; /*Indique le mode d'ouverture du carnet d'adresse*/
      TStringList *slCodeCarnDefaut; /*CodeCarn de la (les) personne(s) qui doit être sélectionnée par
                           défaut au démarrage. Si personne ne doit être pris par
                           défaut, ne rien ajouter*/
      AnsiString aCategorieParDefaut; //Catégorie sélectionnée par défaut                           
      AnsiString aCategoriesVisibles; //Liste de catégories qui doivent être visibles (séparée par des virgules). SI VIDE, toutes les catégories sont visibles
      __fastcall inline sConfigCarnAdr (){slCodeCarnDefaut = new TStringList;};
      virtual __fastcall inline ~sConfigCarnAdr (){delete slCodeCarnDefaut;};
   };

struct TRIB
   {
   char szDesign [NB_CAR_RIB_DESIGNATION];
   char szBanque [NB_CAR_RIB_BANQUE     ];
   char szGuichet[NB_CAR_RIB_GUICHET    ];
   char szCompte [NB_CAR_RIB_COMPTE     ];
   char szCle    [NB_CAR_RIB_CLE        ];
   };

class TInfosIndiv
{
	private :
		TPicture	*m_pSignature;  
		
		void __fastcall inline SetSignature(TPicture *_pSignature) { m_pSignature->Assign(_pSignature); };
		
	public :
		char		szCategorie[NB_CAR_CATEG];
		char		szTitre[NB_CAR_TITRE];
		char 		szNom[NB_CAR_NOM];
		char 		szPrenom[NB_CAR_PRENOM];
		char 		szFonction[NB_CAR_FONCTION];
		char 		szSociete[NB_CAR_SOCIETE];
		char 		szTelephone[NB_CAR_TEL];
		char 		szTelecopie[NB_CAR_FAX];
		char 		szEMail[NB_CAR_EMAIL];
		char 		szSiteInternet[NB_CAR_SITEWEB];
		AnsiString	aCommentaire;
		TRIB		sRIB;	
		
		__fastcall inline TInfosIndiv (){m_pSignature = new TPicture();};		
		virtual __fastcall inline ~TInfosIndiv (){delete m_pSignature;};
		
		__property TPicture *pSignature = { read = m_pSignature , write = SetSignature };	
};

typedef void (*TFctGereCarnet)(const sConfigCarnAdr &sConfig, TList *lstFiches);
typedef bool (*FctChargerFiche)(TYPE_FORMAT Format, TInfosIndiv *sInfosIndiv,
                                void *sAdresse, unsigned long NumFiche);
typedef bool (*FctSauverFiche)(TYPE_FORMAT Format, TInfosIndiv *sInfosIndiv,
                               void *sAdresse, unsigned long NumFiche);
typedef unsigned long (*FctNouvelleFiche) ();
typedef void (*FctSupprimerFiche) (unsigned long NumFiche);
typedef bool (*FctChercherFiche) (short shRecherche,
                                  long nCleCodeCarn,
                                  char szCleSociete[],
                                  char szCleCategorie[],
                                  char szCleNom[],
                                  char szClePrenom[],
                                  TStringList *slResultat);

typedef void (*TFctConstituerDesignation)(const char szSociete[],
                                          const char szTitre[],
                                          const char szNom[],
                                          const char szPrenom[],
                                          const char szFonction[],
                                          const char szCommentaire[],
                                          char szDesignation[]);

typedef void (*TFctConvertirAdresse)(void *sAdresseSource,
                                     TYPE_FORMAT FormatSource,
                                     void *sAdresseCible,
                                     TYPE_FORMAT FormatCible);

//---------------------------------------------------------------------------
extern PACKAGE_CTRLSTD void __fastcall VoirCarnetAdresses();

//Affiche une boite permettant la sélection d'une fiche
extern PACKAGE_CTRLSTD unsigned long  __fastcall SelectUneFiche (unsigned long lCodeCarnDefaut,
                                                                 const AnsiString &aCategoriesAAfficher, //Liste de catégories qui doivent être visibles (séparée par des virgules). SI VIDE, toutes les catégories sont visibles
                                                                 const AnsiString &aCategorieParDefaut
                                                                 );

class PACKAGE_CTRLSTD CAdrRecherche
{
private :
   FctChercherFiche _ChercherFiche;
   HINSTANCE        hCarnAdr;
   TStringList      *slResult;
   unsigned long    ulNumFicheResult;

public :
    AnsiString 	aSociete;
    AnsiString 	aNom;
    AnsiString 	aPrenom;
    AnsiString 	aCategorie;
    unsigned long   ulNumFiche;

  __fastcall CAdrRecherche();
  virtual __fastcall ~CAdrRecherche();

  //Renvoi le nombre de fiche trouvée
  unsigned int __fastcall GetNbResult( void );

    //--- Recherche une ou plusieurs fiches dans le carnet d'adresses
    // shRecherche : indique les champs qui seront utilisés pour la recherche (ADR_REC_xxx)
    // Les valeurs de champs utilisés sont celles de la classe
    // Retourne le numéro de la première fiche trouvée ou 0 s'il n'y en a aucune.
  unsigned long __fastcall DebutRecherche(short shRecherche);
    // EX : Recherche les fiches DUPOND Alain :
    //      Adr->aNom = "DUPOND";
    //      Adr->aPrenom = "Alain";
    //      if ((NoFiche = Adr->DebutRecherche(ADR_REC_NOM |ADR_REC_PRENOM)) != 0)
    //         do {
    //          Traitement sur NoFiches
    //         }while((NoFiche = Adr->RechercheSuivant()) != 0);

  unsigned long __fastcall RechercheSuivant();// Une recherche a dû être faite précédemment
                                              // La recherche du suivant se fait d'après la même clé
};

class PACKAGE_CTRLSTD CAdr
{
public:
    __property AnsiString aDesignation = {read = GetDesignation};
    AnsiString aCategorie;
    AnsiString aTitre;
    AnsiString aNom;
    AnsiString aPrenom;
    AnsiString aSociete;
    AnsiString aFonction;
    AnsiString aTelephone;
    AnsiString aTelecopie;
    AnsiString aEMail;
    AnsiString aSiteInternet;
    AnsiString aCommentaire;
    TRIB sRIB;
    TPicture *pSignature;

private:
    unsigned long   ulNumFiche;
    AnsiString aRepDll;

    TAdresseDetaillee sAdr0;
    TAdresseFormat1 sAdr1;
    TAdresseFormat2 sAdr2;
    TAdresseFormat3 sAdr3;
    TAdresseFormat4 sAdr4;
    TYPE_FORMAT eFormatFiche;

    HINSTANCE         hCarnAdr;

    //Fonction de la Dll CarnAdr
    FctChargerFiche           _ChargerFiche;
    FctSauverFiche            _SauverFiche;
    FctNouvelleFiche          _NouvelleFiche;
    FctSupprimerFiche         _SupprimerFiche;
    TFctGereCarnet            _FctGereCarnet;
    TFctConstituerDesignation _ConstituerDesignation;
    TStringList         *slResult;

    AnsiString __fastcall GetDesignation() const;
    void __fastcall InitContenuFiche();
    void __fastcall ConvertirAdresse(void *sAdresseSource,
                                     TYPE_FORMAT FormatSource,
                                     void *sAdresseCible,
                                     TYPE_FORMAT FormatCible) const;

public:
  //--- CONSTRUCTEURS ---//
  __fastcall CAdr();

  //--- DESTRUCTEURS ---//
  virtual __fastcall ~CAdr();

  //--- Remet à 0 la fiche, à utiliser pour créer une nouvelle fiche ---//
  void __fastcall Init( void );

  //Créé une fiche vierge dans la table
  void __fastcall NouvelleFicheVide();

  //Affiche une boite de dialogue permettant la sélection d'une fiche
  bool  __fastcall SelectUneFiche (TYPE_FORMAT Format = FORMAT_NON_DEFINI,
                                   const AnsiString &aCategoriesAAfficher = EmptyStr,
                                   const AnsiString &aCategorieParDefaut = EmptyStr);

  //--- Charge une fiche à partir de son numéro ---//
  bool __fastcall Charge( unsigned long ulNumFiche, TYPE_FORMAT Format = FORMAT_NON_DEFINI);
    // EX : if (Adr->Charge( dm->TableNumFiche->AsInteger )) {
    //        AdrPanel->Affiche( Adr );
    //      }

  //--- Enregistre cette occurence de CAdr ---//
    // Retourne le numéro de la fiche enregistrée ou 0 si ça s'est mal passé
    // Affecte le numéro de fiche (changement seulement si création)
  unsigned long __fastcall Sauve( void );
    // EX : Adr->Init();
    //      Adr->aNom = "DUPOND";
    //      Adr->aPrenom = "Alain";
    //      Adr->Sauve();
    //      dm->TableNumFiche->AsInteger = Adr->ulNumFiche;
    //      dm->Table->Save();

    //Supprime la fiche
    void __fastcall SupprimerFiche();

    //Copie le contenu de la fiche source (excepté son numéro)
    void __fastcall Assign(const CAdr &cSource);

    //Fontion pour remplir les structures d'adresse
    void __fastcall SetAdr(const TAdresseDetaillee &_sAdr0);
    void __fastcall SetAdr(const TAdresseFormat1 &_sAdr1);
    void __fastcall SetAdr(const TAdresseFormat2 &_sAdr2);
    void __fastcall SetAdr(const TAdresseFormat3 &_sAdr3);
    void __fastcall SetAdr(const TAdresseFormat4 &_sAdr4);

    //Fonction pour lire les structures d'adresse
    void __fastcall GetAdr(TAdresseDetaillee *_sAdrCible)const;
    void __fastcall GetAdr(TAdresseFormat1 *_sAdrCible)const;
    void __fastcall GetAdr(TAdresseFormat2 *_sAdrCible)const;
    void __fastcall GetAdr(TAdresseFormat3 *_sAdrCible)const;
    void __fastcall GetAdr(TAdresseFormat4 *_sAdrCible)const;

    //Retourne le numéro de la fiche
    unsigned long __fastcall GetNumFiche() const;
};

//------------------------------------------------------------------------------
class PACKAGE_CTRLSTD CAdrPanel : public CAdressePanel
{
private:
  CAdr          *Adr;
  TInfosIndiv   m_sInfosIndiv;

private :
  typedef         CAdressePanel inherited;
  void __fastcall SetTypeFormat( TYPE_FORMAT f );
  TYPE_FORMAT __fastcall GetTypeFormat();
  AnsiString __fastcall GetDesignation();

   AnsiString __fastcall GetCategorie() const;
   void __fastcall SetCategorie(const AnsiString aCategorie);
   AnsiString __fastcall GetTitre() const;
   void __fastcall SetTitre(const AnsiString aTitre);
   AnsiString __fastcall GetNom() const;
   void __fastcall SetNom(const AnsiString aNom);
   AnsiString __fastcall GetPrenom() const;
   void __fastcall SetPrenom(const AnsiString aPrenom);
   AnsiString __fastcall GetFonction() const;
   void __fastcall SetFonction(const AnsiString aFonction);
   AnsiString __fastcall GetSociete() const;
   void __fastcall SetSociete(const AnsiString aSociete);
   AnsiString __fastcall GetTelephone() const;
   void __fastcall SetTelephone(const AnsiString aTelephone);
   AnsiString __fastcall GetTelecopie() const;
   void __fastcall SetTelecopie(const AnsiString aTelecopie);
   AnsiString __fastcall GetEMail() const;
   void __fastcall SetEMail(const AnsiString aEMail);
   AnsiString __fastcall GetSiteInternet() const;
   void __fastcall SetSiteInternet(const AnsiString aSiteInternet);
   AnsiString __fastcall GetRIBDesignation() const;
   void __fastcall SetRIBDesignation(AnsiString aDesignation);
   AnsiString __fastcall GetRIBBanque() const;
   void __fastcall SetRIBBanque(AnsiString aBanque);
   AnsiString __fastcall GetRIBGuichet() const;
   void __fastcall SetRIBGuichet(AnsiString aGuichet);
   AnsiString __fastcall GetRIBCompte() const;
   void __fastcall SetRIBCompte(AnsiString aCompte);
   AnsiString __fastcall GetRIBCle() const;
   void __fastcall SetRIBCle(AnsiString aCle);
   TPicture* __fastcall GetSignature();
   void __fastcall SetSignature(TPicture *_pSignature);

public:
  //--- CONSTRUCTEURS ---//
  __fastcall CAdrPanel(TComponent* Owner);

  //--- DESTRUCTEURS ---//
  virtual __fastcall ~CAdrPanel();

  //--- Affiche le contenu de Adr dans le panel ---//
  void __fastcall Afficher(int nNumFiche);

  //--- Lit tous les champs dans le panel et affecte Adr ---//
  unsigned long __fastcall Enregistrer( void );

  //--- Efface tous les champs dans le panel ---//
  void __fastcall Vider();

  // Crée une nouvelle fiche
  unsigned long  __fastcall Nouveau();

__published:
  __property BevelInner;
  __property BevelOuter;
  __property AfficheLabel;
  __property TYPE_FORMAT TypeFormat    = { read = GetTypeFormat, write = SetTypeFormat, default = FORMAT_1 };
  __property AnsiString Designation    = { read = GetDesignation};
  __property AnsiString Categorie      = { read = GetCategorie, write = SetCategorie};
  __property AnsiString Titre          = { read = GetTitre, write = SetTitre};
  __property AnsiString Nom            = { read = GetNom, write = SetNom};
  __property AnsiString Prenom         = { read = GetPrenom, write = SetPrenom};
  __property AnsiString Fonction       = { read = GetFonction, write = SetFonction};
  __property AnsiString Societe        = { read = GetSociete, write = SetSociete};
  __property AnsiString Telephone      = { read = GetTelephone, write = SetTelephone};
  __property AnsiString Telecopie      = { read = GetTelecopie, write = SetTelecopie};
  __property AnsiString EMail          = { read = GetEMail, write = SetEMail};
  __property AnsiString SiteInternet   = { read = GetSiteInternet, write = SetSiteInternet};
  __property AnsiString Commentaire    = { read = m_sInfosIndiv.aCommentaire, write = m_sInfosIndiv.aCommentaire};
  __property AnsiString RIBDesignation = { read = GetRIBDesignation, write = SetRIBDesignation};
  __property AnsiString RIBBanque      = { read = GetRIBBanque     , write = SetRIBBanque     };
  __property AnsiString RIBGuichet     = { read = GetRIBGuichet    , write = SetRIBGuichet    };
  __property AnsiString RIBCompte      = { read = GetRIBCompte     , write = SetRIBCompte     };
  __property AnsiString RIBCle         = { read = GetRIBCle        , write = SetRIBCle        };
  __property TPicture *Signature        = { read = GetSignature     , write = SetSignature     };
};

#endif
